﻿#region Copyright(C) 2013 NCS Pte. Ltd. All rights reserved.

// ==================================================================================================
// Copyright(C) 2013 NCS Pte. Ltd. All rights reserved.
//
// SYSTEM NAME	:   iConnect.Azure Application Framework
// COMPONENT ID :   NCS.IConnect.Azure.Diagnostics.CloudServiceRuntime.ParallelRoleEntryPoint
// COMPONENT DESC:  	
//
// CREATED DATE/BY:  20 Dec 2012 / Lu Ya Ming
//
// REVISION HISTORY:	
// DATE/BY			SR#/CS/PM#/OTHERS		DESCRIPTION OF CHANGE
// ==================================================================================================

#endregion

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

using Microsoft.WindowsAzure.ServiceRuntime;

namespace NCS.IConnect.Cloud.Core.CloudServiceRuntime
{
    /// <summary>
    /// The worker role entry point based TPL.
    /// </summary>
    public abstract class ParallelRoleEntryPoint : RoleEntryPoint
    {
        private List<Task> Tasks = new List<Task>();
        private WorkerEntryPoint[] Workers;

        /// <summary>
        /// Runs tasks based current worker role.
        /// </summary>
        public override void Run()
        {
            // Adds all of workers into current worker list.
            foreach (WorkerEntryPoint worker in Workers)
            {
                Tasks.Add(new Task(worker.ProtectedRun));
            }

            // Invokes all of the tasks.
            Tasks.ForEach(task => task.Start());

            // Wait to exit until all of the tasks are completed.
            Task.WaitAll(Tasks.ToArray());
        }

        /// <summary>
        /// To initialize worker role from OnStart.
        /// </summary>
        /// <param name="workers">The workers.</param>
        /// <returns>Unstarted/Started</returns>
        public bool OnStart(WorkerEntryPoint[] workers)
        {
            this.Workers = workers;
            foreach (WorkerEntryPoint worker in workers)
            {
                worker.OnStart();
            }

            return base.OnStart();
        }

        /// <summary>
        /// Override the OnStart.
        /// </summary>
        /// <returns></returns>
        public override bool OnStart()
        {
            throw new InvalidOperationException();
        }

        /// <summary>
        /// Performs extra logic during stopping the current worker.
        /// </summary>
        public override void OnStop()
        {
            // Disposes all of the tasks.
            Tasks.ForEach(task =>
                {
                    task.Dispose();
                });

            // Forces to stop the paralleled workers.
            foreach (WorkerEntryPoint worker in Workers)
            {
                worker.OnStop();
            }

            base.OnStop();
        }

    }
}
